package org.zxw.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.reactive.function.client.WebClient;
import org.zxw.service.AiTrainingPlanService;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AiTrainingPlanServiceImpl implements AiTrainingPlanService {
    private final WebClient deepseekWebClient;
    private final RedisTemplate<String, Object> redisTemplate;
    private final String model;
    //限流操作用微服务
    //private final RateLimiter rateLimiter;

    public AiTrainingPlanServiceImpl(WebClient deepseekWebClient,
                                     RedisTemplate<String, Object> redisTemplate,
                                     @Value("${deepseek.model}") String model,
                                     @Value("${ai.rate.limit:5}") int rateLimit) {
        this.deepseekWebClient = deepseekWebClient;
        this.redisTemplate = redisTemplate;
        this.model = model;
    }

    /**
     * 根据用户描述和运动水平生成训练计划
     * @param userDescription
     * @param fitnessLevel
     * @return
     */
    public String generateTrainingPlan(String userDescription, String fitnessLevel) {
        String cacheKey = "ai:plan:" + DigestUtils.md5DigestAsHex((userDescription + fitnessLevel).getBytes());
        
        Object cached = redisTemplate.opsForValue().get(cacheKey);
        if (cached != null) {
            return (String) cached;
        }
        
        String prompt = buildPrompt(userDescription, fitnessLevel);
        
        try {
            // DeepSeek API请求结构
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", model);
            requestBody.put("messages", Collections.singletonList(
                    Map.of("role", "user", "content", prompt)
            ));
            requestBody.put("temperature", 0.7);
            requestBody.put("max_tokens", 1000);
            
            String response = deepseekWebClient.post()
                    .uri("/chat/completions")
                    .bodyValue(requestBody)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .map(result -> {
                        // 解析DeepSeek响应结构
                        List<Map<String, Object>> choices = (List<Map<String, Object>>) result.get("choices");
                        return (String) ((Map<String, Object>) choices.get(0).get("message")).get("content");
                    })
                    .block();
            
            redisTemplate.opsForValue().set(cacheKey, response, 7, TimeUnit.DAYS);
            return response;
        } catch (Exception e) {
            log.error("DeepSeek健身计划生成失败", e);
            throw new RuntimeException("生成健身计划时出错，请稍后再试");
        }
    }

    // 构建DeepSeek请求体
    private String buildPrompt(String userDescription, String fitnessLevel) {
        return String.format(
            "你是一位专业的健身教练。请根据以下信息为学员制定一份健身计划：\n" +
            "学员描述：%s\n" +
            "健身水平：%s\n\n" +
            "请按照以下格式提供计划：\n" +
            "1. 计划名称\n" +
            "2. 适合人群\n" +
            "3. 训练目标\n" +
            "4. 每周训练频率\n" +
            "5. 每次训练时长\n" +
            "6. 详细训练内容（分部位或分日）\n" +
            "7. 饮食建议（简要）\n" +
            "8. 注意事项\n\n" +
            "请使用专业但易懂的语言，避免使用过于专业的术语。",
            userDescription, fitnessLevel);
    }
}